package com.dj.mingkong.portal.biz.service.music.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dj.mingkong.common.enums.StatusEnum;
import com.dj.mingkong.common.exception.ValidateException;
import com.dj.mingkong.common.infrastructure.base.dto.context.UserInfoContext;
import com.dj.mingkong.common.infrastructure.eo.database.music.AlbumCollectEo;
import com.dj.mingkong.common.infrastructure.eo.database.music.AlbumEo;
import com.dj.mingkong.common.microservice.UserContext;
import com.dj.mingkong.common.util.AssertUtils;
import com.dj.mingkong.common.util.SmartBeanCopy;
import com.dj.mingkong.portal.biz.controller.music.vo.request.AlbumCollectAddVo;
import com.dj.mingkong.portal.biz.controller.music.vo.request.AlbumCollectCancelVo;
import com.dj.mingkong.portal.biz.controller.music.vo.request.AlbumCollectQueryVo;
import com.dj.mingkong.portal.biz.controller.music.vo.response.AlbumCollectDetailVo;
import com.dj.mingkong.portal.biz.controller.music.vo.response.AlbumCollectVo;
import com.dj.mingkong.portal.biz.core.base.context.UserContextHolder;
import com.dj.mingkong.portal.biz.repository.database.music.AlbumCollectRepository;
import com.dj.mingkong.portal.biz.repository.database.music.AlbumRepository;
import com.dj.mingkong.portal.biz.service.music.AlbumCollectService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * 专辑收藏服务实现
 *
 * @author zenglonghui
 * @date: 2022/8/25 9:27
 */
@Slf4j
@Service("albumCollectService")
public class AlbumCollectServiceImpl implements AlbumCollectService {
    @Resource
    private AlbumCollectRepository albumCollectRepository;
    @Resource
    private UserContextHolder userContextHolder;
    @Resource
    private AlbumRepository albumRepository;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void handle(AlbumCollectAddVo addVo) {
        final AlbumEo albumEo = albumRepository.getById(addVo.getAlbumId());
        AssertUtils.isNotNull(albumEo, "albumEo invalid");
        final Optional<AlbumCollectEo> optional = albumCollectRepository
                .oneOptByUserIdAndAlbumId(UserContext.getUserId(), addVo.getAlbumId());
        optional.ifPresentOrElse(albumCollectEo -> {
            if (StatusEnum.VALID.equalsIntVal(albumCollectEo.getStatus())) {
                //取消关注
                albumCollectEo.setStatus(StatusEnum.INVALID.getIntVal());
                albumRepository.updateById(albumEo.setCollectCount(albumEo.getCollectCount() - 1));
            } else {
                albumCollectEo.setStatus(StatusEnum.VALID.getIntVal());
                albumRepository.updateById(albumEo.setCollectCount(albumEo.getCollectCount() + 1));
            }
            albumCollectEo.setType(addVo.getType());
            albumCollectRepository.updateById(albumCollectEo);
        }, () -> {
            final AlbumCollectEo collectEo = AlbumCollectEo.builder().albumId(addVo.getAlbumId())
                    .status(StatusEnum.VALID.getIntVal()).userId(UserContext.getUserId())
                    .type(addVo.getType()).build();
            albumCollectRepository.save(collectEo);
            albumRepository.updateById(albumEo.setCollectCount(albumEo.getCollectCount() + 1));
        });
    }

    @Override
    public AlbumCollectDetailVo getAlbumCollect(Long albumId) {
        final Optional<UserInfoContext> currentUserOpt = userContextHolder.getCurrentUserOpt();
        if (currentUserOpt.isEmpty()) {
            return AlbumCollectDetailVo.builder().albumId(albumId).status(StatusEnum.INVALID.getIntVal())
                    .build();
        }
        final UserInfoContext currentUser = currentUserOpt.get();
        final Optional<AlbumCollectEo> optional = albumCollectRepository.oneOptByUserIdAndAlbumId(currentUser.getId(), albumId);
        if (optional.isEmpty()) {
            return AlbumCollectDetailVo.builder().albumId(albumId).status(StatusEnum.INVALID.getIntVal())
                    .userId(currentUser.getId()).build();
        }
        return SmartBeanCopy.copy(optional.get(), AlbumCollectDetailVo.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(AlbumCollectAddVo addVo) {
        final AlbumEo albumEo = albumRepository.getById(addVo.getAlbumId());
        AssertUtils.isNotNull(albumEo, "albumId invalid");
        final Optional<AlbumCollectEo> optional = albumCollectRepository
                .oneOptByUserIdAndAlbumId(UserContext.getUserId(), addVo.getAlbumId());
        optional.ifPresentOrElse(albumCollectEo -> {
            if (StatusEnum.VALID.equalsIntVal(albumCollectEo.getStatus())) {
                throw new ValidateException("已收藏");
            }
            albumCollectEo.setStatus(StatusEnum.VALID.getIntVal());
            albumCollectEo.setType(addVo.getType());
            albumCollectRepository.updateById(albumCollectEo);
            albumRepository.updateById(albumEo.setCollectCount(albumEo.getCollectCount() + 1));
        }, () -> {
            final AlbumCollectEo collectEo = AlbumCollectEo.builder().albumId(addVo.getAlbumId())
                    .status(StatusEnum.VALID.getIntVal()).userId(UserContext.getUserId())
                    .type(addVo.getType()).build();
            albumCollectRepository.save(collectEo);
            albumRepository.updateById(albumEo.setCollectCount(albumEo.getCollectCount() + 1));
        });
    }

    @Override
    public Page<AlbumCollectVo> pageByVo(AlbumCollectQueryVo queryVo) {
        return albumCollectRepository.getMapper().listPage(Page.of(queryVo.getPage(), queryVo.getPageSize()), queryVo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cancel(AlbumCollectCancelVo cancelVo) {
        final AlbumEo albumEo = albumRepository.getById(cancelVo.getAlbumId());
        AssertUtils.isNotNull(albumEo, "AlbumId invalid");
        final Optional<AlbumCollectEo> optional = albumCollectRepository
                .oneOptByUserIdAndAlbumId(UserContext.getUserId(), cancelVo.getAlbumId());
        optional.ifPresent(albumCollectEo -> {
            if (StatusEnum.VALID.equalsIntVal(albumCollectEo.getStatus())) {
                albumCollectEo.setStatus(StatusEnum.INVALID.getIntVal());
                albumCollectRepository.updateById(albumCollectEo);
                albumRepository.updateById(albumEo.setCollectCount(albumEo.getCollectCount() - 1));
            }
        });
    }
}
